package com.he.start;

import com.he.handler.SimpleHandler;
import com.he.utils.ApplicationProperty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author HEHUIJUN
 */
public class AppStart {
    //发布端口
    private final static int port=Integer.parseInt(ApplicationProperty.getValueByKey("app.port"));
    private static final Logger logger= LoggerFactory.getLogger(AppStart.class);

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup parent = new NioEventLoopGroup();
        EventLoopGroup child =new NioEventLoopGroup();
        // 1、服务启动引导程序
        ServerBootstrap serverBootstrap=new ServerBootstrap();
        // 2、绑定线程组，parent接收请求，child对请求进行处理
        serverBootstrap.group(parent,child);
        logger.info("绑定线程组完毕");
        // 3、设置服务频道类型
        serverBootstrap.channel(NioServerSocketChannel.class);
        // 4、设置处理器
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                //对请求,响应编码
                ch.pipeline().addLast(new HttpServerCodec());
                //对象聚合器
                ch.pipeline().addLast(new HttpObjectAggregator(1024*64));

                //分块编写处理程序
                ch.pipeline().addLast(new ChunkedWriteHandler());
                //自己的处理器
                ch.pipeline().addLast(new SimpleHandler());
            }
        });
        logger.info("添加处理器完毕");
        serverBootstrap.option(ChannelOption.SO_BACKLOG,128);
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE,true);

        logger.info("绑定端口完毕");
        // 5.绑定端口 阻塞在这里
        ChannelFuture channelFuture=serverBootstrap.bind(AppStart.port).sync();

        // 6.端口没有绑定成功才有返回值
        channelFuture.channel().closeFuture().sync();
        logger.info("绑定端口失败");
        // 7、关闭两个线程池
        parent.shutdownGracefully();
        child.shutdownGracefully();
    }
}
